import json
import os

def parse_operand(operand):
    """解析操作数，返回适合map数组的格式"""
    name = operand.get("name", "")
    immediate = operand.get("immediate", False)
    
    # 处理特殊情况
    if name == "HL" and not immediate:
        return "MHL"  # 内存引用 (HL)
    elif name == "BC" and not immediate:
        return "MBC"  # 内存引用 (BC)
    elif name == "DE" and not immediate:
        return "MDE"  # 内存引用 (DE)
    elif name == "a16" and not immediate:
        return "M16"  # 内存引用 (a16)
    elif name == "a8" and not immediate:
        return "M8"   # 内存引用 (a8)
    elif name.startswith("n"):
        return name   # 立即数 n8, n16
    elif name.startswith("e"):
        return name   # 相对地址 e8
    elif name.startswith("a"):
        return name   # 绝对地址 a8, a16
    else:
        return name   # 寄存器名称

def generate_map_entry(opcode, data):
    """为给定的操作码生成map数组条目"""
    mnemonic = data.get("mnemonic", "")
    operands = data.get("operands", [])
    
    # 初始化条目
    entry = {
        "op_code": mnemonic,
        "d_reg1": None,
        "s_reg2": None,
        "d_mem1": None,
        "s_mem2": None,
        "d_n": None,
        "s_n": None
    }
    
    # 根据操作数类型填充条目
    if len(operands) >= 1:
        op1 = operands[0]
        name1 = parse_operand(op1)
        immediate1 = op1.get("immediate", False)
        
        if immediate1:
            if name1.startswith("n") or name1.startswith("e") or name1.startswith("a"):
                entry["s_n"] = name1
            else:
                entry["d_reg1"] = name1
        else:
            entry["d_mem1"] = name1
    
    if len(operands) >= 2:
        op2 = operands[1]
        name2 = parse_operand(op2)
        immediate2 = op2.get("immediate", False)
        
        if immediate2:
            if name2.startswith("n") or name2.startswith("e") or name2.startswith("a"):
                entry["s_n"] = name2
            else:
                entry["s_reg2"] = name2
        else:
            entry["s_mem2"] = name2
    
    # 特殊情况处理
    # LD (BC),A -> LD NULL,A,MBC,NULL
    if mnemonic == "LD" and len(operands) == 2:
        op1 = operands[0]
        op2 = operands[1]
        name1 = op1.get("name", "")
        name2 = op2.get("name", "")
        imm1 = op1.get("immediate", False)
        imm2 = op2.get("immediate", False)
        
        # 如果是内存写入操作
        if not imm1 and name1 in ["BC", "DE", "HL"] and imm2:
            entry["d_reg1"] = None
            entry["s_reg2"] = name2
            entry["d_mem1"] = "M" + name1
            entry["s_mem2"] = None
        
        # 如果是内存读取操作
        elif imm1 and not imm2 and name2 in ["BC", "DE", "HL"]:
            entry["d_reg1"] = name1
            entry["s_reg2"] = None
            entry["d_mem1"] = None
            entry["s_mem2"] = "M" + name2
    
    # 处理特殊的LD (a16),SP指令
    if mnemonic == "LD" and len(operands) == 2:
        op1 = operands[0]
        op2 = operands[1]
        name1 = op1.get("name", "")
        name2 = op2.get("name", "")
        
        if name1 == "a16" and name2 == "SP":
            entry["d_reg1"] = "SP"
            entry["s_n"] = "M16"
    
    # 格式化为C代码字符串
    values = []
    for key in ["op_code", "d_reg1", "s_reg2", "d_mem1", "s_mem2", "d_n", "s_n"]:
        value = entry[key]
        if value is not None:
            values.append(f'"{value}"')
        else:
            values.append("NULL")
    
    return f"[0x{opcode}] = {{{', '.join(values)}}}"

def main():
    # 读取Opcodes.txt
    with open("Opcodes.txt", "r") as f:
        opcodes_data = json.load(f)
    
    # 生成map数组条目
    entries = []
    
    # 处理unprefixed指令 (0x00-0xFF)
    for opcode, data in opcodes_data["unprefixed"].items():
        hex_opcode = opcode.replace("0x", "")
        entries.append(generate_map_entry(hex_opcode, data))
    
    # 处理cbprefixed指令 (0x100-0x1FF)
    for opcode, data in opcodes_data["cbprefixed"].items():
        hex_opcode = opcode.replace("0x", "")
        # cbprefixed指令的索引从0x100开始
        entries.append(generate_map_entry(f"100+0x{hex_opcode}", data))
    
    # 生成完整的ins.c文件
    ins_c_content = """#include <stdint.h>
#include <stdio.h>
struct Ins
{
    char * op_code;
    char * d_reg1;
    char * s_reg2;
    char * d_mem1;
    char * s_mem2;
    char * d_n;
    char * s_n;
};
struct Ins map[0x512]={
    """ + ",\n    ".join(entries) + """
};
"""
    
    # 写入ins.c文件
    with open("ins.c", "w") as f:
        f.write(ins_c_content)
    
    print("Generated ins.c successfully!")

if __name__ == "__main__":
    main()